<?php

namespace Database\Factories;

use App\Models\Post;
use App\Models\User;
use App\Models\Category;
use App\Models\PostRevision;
use App\Services\PostService;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Config;
use ReflectionClass;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
 */
class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition(): array
    {
        $title = $this->faker->randomElement(Config::get('content.post_titles'));
        $content = $this->generateContent();
        $createdAt = $this->faker->dateTimeBetween('-1 year', 'now');

        // 90% 概率文章为已发布状态
        $isPublished = $this->faker->boolean(90);
        $publishedAt = $isPublished ? $createdAt : null;
        
        // 生成唯一的slug
        $baseSlug = Str::slug($title);
        $slug = $baseSlug . '-' . Str::random(8);

        // 使用 PostService 的 generateExcerpt 方法生成摘要
        $excerpt = $this->generateExcerpt($content);

        return [
            'title' => $title,
            'slug' => $slug,
            'content' => $content,
            'editor_type' => 'markdown',
            'excerpt' => $excerpt,
            'featured_image' => 'https://dummyimage.com/600x400/000/fff',
            'author_id' => User::factory(),
            'views' => $this->faker->numberBetween(0, 1000),
            'created_at' => $createdAt,
            'updated_at' => $this->faker->dateTimeBetween($createdAt, 'now'),
            'published_at' => $publishedAt,
            'status' => $isPublished ? 'published' : 'draft'
        ];
    }

    /**
     * 使用 PostService 生成摘要
     */
    protected function generateExcerpt(string $content): string
    {
        $postService = new PostService();
        $reflection = new ReflectionClass($postService);
        $method = $reflection->getMethod('generateExcerpt');
        $method->setAccessible(true);
        
        return $method->invoke($postService, $content);
    }

    private function generateContent(): string
    {
        $template = $this->faker->randomElement(Config::get('content.post_templates'));
        
        // 如果没有获取到模板，生成一个默认的 Markdown 内容
        if (!isset($template['content'])) {
            return $this->generateDefaultMarkdownContent();
        }
        
        // 确保内容是 Markdown 格式
        $content = $template['content'];
        if (!str_contains($content, '#') && !str_contains($content, '```')) {
            $content = $this->convertToMarkdown($content);
        }
        
        return $content;
    }

    private function generateDefaultMarkdownContent(): string
    {
        // 中文段落模板
        $introParagraphs = [
            '在现代软件开发中，技术选型和架构设计至关重要。本文将深入探讨相关主题，帮助开发者更好地理解和应用。',
            '随着技术的不断发展，我们需要不断学习和实践。本文将从实际项目经验出发，分享一些实用的技巧和方法。',
            '在开发过程中，我们经常会遇到各种挑战。本文将从多个角度分析问题，并提供相应的解决方案。',
        ];
        
        $mainParagraphs = [
            '首先，我们需要理解核心概念。这是整个技术栈的基础，只有深入理解才能更好地应用。',
            '其次，实践是检验真理的唯一标准。通过实际项目，我们可以验证理论的正确性。',
            '最后，持续学习和改进是保持竞争力的关键。技术更新迭代很快，我们需要跟上步伐。',
            '此外，团队协作和沟通也非常重要。良好的协作能够提高开发效率。',
            '同时，代码质量和可维护性也是我们需要关注的重点。',
        ];
        
        $summaryParagraphs = [
            '通过本文的学习，我们了解了相关技术的核心概念和最佳实践。希望这些内容能够帮助你在实际项目中更好地应用。',
            '总结一下，这些方法和技巧都是经过实践验证的，可以放心使用。同时也欢迎大家在实践中不断优化和改进。',
            '最后，希望本文能够对你有所帮助。如果你有任何问题或建议，欢迎在评论区留言讨论。',
        ];
        
        $title = $this->faker->randomElement(Config::get('content.post_titles'));
        $intro = $this->faker->randomElement($introParagraphs);
        $summary = $this->faker->randomElement($summaryParagraphs);
        
        $content = "# {$title}\n\n";
        $content .= "## 简介\n\n";
        $content .= $intro . "\n\n";
        $content .= "## 主要内容\n\n";
        
        // 随机选择3-5个主要段落
        $selectedParagraphs = $this->faker->randomElements($mainParagraphs, rand(3, 5));
        foreach ($selectedParagraphs as $index => $paragraph) {
            $sectionTitles = [
                '核心概念',
                '实践方法',
                '最佳实践',
                '常见问题',
                '优化建议',
                '案例分析',
            ];
            
            $content .= "### " . $sectionTitles[$index % count($sectionTitles)] . "\n\n";
            $content .= $paragraph . "\n\n";
            
            // 添加一些 Markdown 元素
            if (rand(0, 1)) {
                $listItems = [
                    '理解核心概念',
                    '掌握实践方法',
                    '遵循最佳实践',
                    '持续优化改进',
                ];
                $selectedItems = $this->faker->randomElements($listItems, rand(2, 4));
                foreach ($selectedItems as $item) {
                    $content .= "- {$item}\n";
                }
                $content .= "\n";
            }
            
            if (rand(0, 1)) {
                $codeExamples = [
                    "```php\npublic function example() {\n    return '这是一个示例代码';\n}\n```",
                    "```javascript\nconst example = () => {\n    return '这是一个示例代码';\n};\n```",
                    "```bash\n# 这是一个命令示例\necho 'Hello World'\n```",
                ];
                $content .= $this->faker->randomElement($codeExamples) . "\n\n";
            }
        }
        
        $content .= "## 总结\n\n";
        $content .= $summary . "\n\n";
        
        return $content;
    }

    private function convertToMarkdown(string $content): string
    {
        $lines = explode("\n", $content);
        $markdown = '';
        $inCodeBlock = false;
        
        foreach ($lines as $line) {
            $line = trim($line);
            if (empty($line)) {
                $markdown .= "\n\n";
                continue;
            }
            
            // 如果看起来像标题，但没有 Markdown 格式
            if (strlen($line) < 50 && !str_contains($line, '.')) {
                $markdown .= "## " . $line . "\n\n";
                continue;
            }
            
            // 处理代码块
            if (str_contains($line, 'function') || str_contains($line, 'class') || str_contains($line, '<?php')) {
                if (!$inCodeBlock) {
                    $markdown .= "```php\n";
                    $inCodeBlock = true;
                }
                $markdown .= $line . "\n";
                continue;
            }
            
            if ($inCodeBlock && !str_contains($line, 'function') && !str_contains($line, 'class')) {
                $markdown .= "```\n\n";
                $inCodeBlock = false;
            }
            
            // 处理普通段落
            $markdown .= $line . "\n\n";
        }
        
        return $markdown;
    }

    public function configure()
    {
        return $this->afterCreating(function (Post $post) {
            // 创建版本历史（减少版本数量）
            $versions = $this->faker->numberBetween(1, 2);
            for ($i = 1; $i <= $versions; $i++) {
                $meta = [
                    'category_id' => $post->category_id,
                    'category_name' => $post->category ? $post->category->name : null,
                    'tags' => $post->tags ? $post->tags->pluck('id')->toArray() : [],
                    'tag_names' => $post->tags ? $post->tags->pluck('name')->toArray() : [],
                ];
                
                PostRevision::factory()->create([
                    'post_id' => $post->id,
                    'user_id' => $post->author_id,
                    'content' => $this->generateModifiedContent($post->content, $i),
                    'title' => $this->generateModifiedTitle($post->title, $i),
                    'excerpt' => $this->generateExcerpt($this->generateModifiedContent($post->content, $i)),
                    'reason' => $this->faker->randomElement([
                        '修复了一些错误',
                        '优化了文章结构',
                        '更新了内容',
                        '完善了代码示例',
                        '改进了表达方式',
                        '添加了新的章节',
                    ]),
                    'meta' => $meta,
                ]);
            }
        });
    }

    private function generateModifiedContent($originalContent, $version)
    {
        // 简单的内容修改逻辑
        return str_replace(
            ['深入理解', '最佳实践', '实战指南', '总结'],
            ['深入理解（版本' . $version . '）', '最佳实践（版本' . $version . '）', '实战指南（版本' . $version . '）', '总结（版本' . $version . '）'],
            $originalContent
        );
    }

    private function generateModifiedTitle($originalTitle, $version)
    {
        return $originalTitle . '（版本' . $version . '）';
    }

    public function published(): static
    {
        return $this->state(function (array $attributes) {
            return [
                'published_at' => $this->faker->dateTimeBetween('-1 year', 'now'),
            ];
        });
    }

    public function draft(): static
    {
        return $this->state(function (array $attributes) {
            return [
                'published_at' => null,
            ];
        });
    }

    public function featured(): static
    {
        return $this->state(function (array $attributes) {
            return [
                'featured_image' => $this->faker->imageUrl(1200, 800, 'technology'),
                'views' => $this->faker->numberBetween(1000, 5000),
            ];
        });
    }

    public function popular(): static
    {
        return $this->state(function (array $attributes) {
            return [
                'views' => $this->faker->numberBetween(5000, 10000),
            ];
        });
    }

    public function recent(): static
    {
        return $this->state(function (array $attributes) {
            return [
                'created_at' => $this->faker->dateTimeBetween('-1 month', 'now'),
                'published_at' => $this->faker->dateTimeBetween('-1 month', 'now'),
            ];
        });
    }
}
